(define (flatmap proc li) 
  (if (null? li) 
      '() 
      (let ((result (proc (car li))) 
            (rest (flatmap proc (cdr li)))) 
        (if (pair? result) 
            (append result rest) 
            (cons result rest))))) 

(define (remove seq elt)
  (filter (lambda (x) (not (eq? x elt))) seq))

(define (combination seq)
  (if (null? (cdr seq))
      (list seq)
      (flatmap (lambda (x)
                 (map (lambda (y) (cons x y))
                      (combination (remove seq x))))
               seq)))

(define (permutations lists) 
  (if (null? lists) 
      '(()) 
      (flatmap (lambda (x)  
                 (map (lambda (y) (cons x y))  
                      (permutations (cdr lists)))) 
               (car lists))))

(define (filter proc seq)
  (if (null? seq)
      '()
      (if (proc (car seq))
          (cons (car seq) (filter proc (cdr seq)))
          (filter proc (cdr seq)))))

(define (solve-problem)
  (define (xor pre1 pre2)
    (or (and pre1 (not pre2))
        (and (not pre1) pre2)))
  
  (define constraint
    (lambda (betty ashille joan catty mary)
      (and (xor (= catty 2) (= betty 3))
           (xor (= ashille 1) (= joan 2))
           (xor (= joan 3) (= ashille 5))
           (xor (= catty 2) (= mary 4))
           (xor (= mary 4) (= betty 1)))))

  (filter (lambda (alternative)
            (apply constraint alternative))
          (combination '(1 2 3 4 5))))

(solve-problem)